/*
 * Desenvolvido para a disciplina Desenvolvimento de Aplicações Web.
 * Curso Tecnologia em Telematica.
 * Instituto Federal de Educação, Ciência e Tecnologia.
 */

package sql;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.sql.Connection;

import core.Aluno;
import core.Curso;
import sql.BancoDados;

/**
 * SAW - Sistema Academica Web.
 * Classe de tratamento do Banco de Dados para a classe Aluno.
 *
 * @author Antonio Carlos Trajano de Oliveira, antonio.c.trajano@gmail.com
 * @author Icaro Vasconcelos Souza, icaroswim@gmail.com
 * @version 1.0
 */
public class AlunoBD {
	
	private Connection con;
	
	public AlunoBD() {
		try {
			Class.forName(BancoDados.driverJDBC);
			con = DriverManager.getConnection(BancoDados.dbMySQL, BancoDados.usuario, BancoDados.senha);
			con.setAutoCommit( false );
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public void close() throws ConexaoException {
		try {
			
			Class.forName(BancoDados.driverJDBC);
			con.commit();
			con.close();
			
		} catch (SQLException e) {
			throw new ConexaoException( e.getMessage() );
		} catch (ClassNotFoundException e) {
			throw new ConexaoException( e.getMessage() );
		}
		
	}
	
	public void addAluno( String nome, String matricula ) throws AlunoException {
		Statement st;
		
		if( existeAlunoNome(nome) ) {
			throw new AlunoException( "Nome do Aluno já existe." );
		}
		
		if( existeAlunoMatricula(matricula) ) {
			throw new AlunoException( "Matricula do Aluno já existe." );
		}
		
		try {
			
			st = con.createStatement();
			st.execute( comandoCadastraAluno(nome, matricula) );
			
			con.commit();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public ArrayList<Aluno> getAlunos( String nomeAluno ) throws ConexaoException {
		Statement st;
		ResultSet rs;
		
		ArrayList<Aluno> lstAluno = new ArrayList<Aluno>();
		
		try {
			
			st = con.createStatement();
			rs = st.executeQuery( comandoPesquisaAluno( nomeAluno ) );
			
			while( rs.next() ) {
				
				// Criação do objeto Aluno temporario que irá ser adicionado na
				// lista de Alunos encontrados na Query SQL.
				Aluno tempAluno = new Aluno( rs.getString("nome"), rs.getString("matricula") );
				
				// Verifica e adiciona (caso exista) os Cursos que o Aluno esta matriculado.
				for( int i = 1; i <= 3; i++ ) {
					Curso tempCurso;
					int idCurso = rs.getInt("id_curso" + i);
					if( idCurso != 0 ) {
						CursoBD sqlCurso = new CursoBD();
						tempCurso = sqlCurso.getCursoPorID( idCurso );
						tempAluno.addCurso( tempCurso );
					}
				}
				
				lstAluno.add( tempAluno );
				
				con.commit();
				
			}
		} catch (SQLException e) {
			throw new ConexaoException( e.getMessage() );
		}
		
		return lstAluno;
	}
	
	public Aluno getAluno( String matricula ) throws AlunoException {
		Statement st;
		ResultSet rs;
		Aluno tempAluno = new Aluno();
		
		if( ! existeAlunoMatricula(matricula) ) {
			throw new AlunoException("Matricula Aluno não existe.");
		}
		
		try {
			
			st = con.createStatement();
			rs = st.executeQuery( comandoAlunoMatricula(matricula) );
			
			if( rs.next() ) {
				
				tempAluno.setNome( rs.getString("nome") );
				tempAluno.setMatricula( rs.getString("matricula") );
				
				for( int i = 1; i <= 3; i++ ) {
					Curso tempCurso;
					int idCurso = rs.getInt("id_curso" + i);
					if( idCurso != 0 ) {
						CursoBD bdCurso = new CursoBD();
						tempCurso = bdCurso.getCursoPorID( idCurso );
						tempAluno.addCurso( tempCurso );
						bdCurso.close();
					}
				}
				
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return tempAluno;
	}
	
	public void delAluno( String matricula ) throws AlunoException {
		Statement st;
		
		if( !existeAlunoMatricula(matricula) ) {
			throw new AlunoException( "Matricula não existe." );
		}
		
		try {
			
			st = con.createStatement();
			st.execute( comandoRemoveAlunoMatricula( matricula ));
			con.commit();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public boolean updateAluno( Aluno aluno, String matriculaAntiga ) { 
		Statement st;

		try {
			
			CursoBD bd = new CursoBD();
			
			st = con.createStatement();
			st.execute( comandoAtualizaAluno( aluno.getNome(),
					aluno.getMatricula(),
					bd.getIDCurso( aluno.getCurso(0) ),
					bd.getIDCurso( aluno.getCurso(1) ),
					bd.getIDCurso( aluno.getCurso(2) ),
					matriculaAntiga ) );

			con.commit();

		} catch (SQLException e) {
			e.printStackTrace();
		} catch (CursoException e) {
			e.printStackTrace();
		} catch (AlunoException e) {
			e.printStackTrace();
		}
		
		return true;
	}

	private boolean existeAlunoMatricula( String matricula ) {
		
		Statement st;
		ResultSet rs;
		
		try {
			
			st = con.createStatement();
			rs = st.executeQuery( comandoMatriculaAluno(matricula) );
			
			int resultado = -1;
			
			if( rs.next() ) {
				resultado = rs.getInt( "id" );
			}
			
			con.commit();
			
			if( resultado < 1 ) {
				return false;
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return true;
		
	}
	
	private boolean existeAlunoNome( String nome ) {
		
		Statement st;
		ResultSet rs;

		try {
			
			st = con.createStatement();
			rs = st.executeQuery( comandoNomeAluno( nome ) );
			
			int resultado = -1;
			
			if( rs.next() ) {
				resultado = rs.getInt( "id" );
			}
			
			con.commit();
			
			if( resultado < 1 ) {
				return false;
			}
			
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return true;
	}
	
	private String comandoAtualizaAluno(String nome, String matricula, int idCurso1, int idCurso2, int idCurso3, String matriculaAntiga ) {
		String idCurso1F = "" + idCurso1;
		String idCurso2F = "" + idCurso2;
		String idCurso3F = "" + idCurso3;
		if( idCurso1 < 1 ) {
			idCurso1F = "NULL";
		}
		if( idCurso2 < 1 ) {
			idCurso2F = "NULL";
		}
		if( idCurso3 < 1 ) {
			idCurso3F = "NULL";
		}
		String saida = "UPDATE aluno SET nome = '" + nome + "' , matricula = '" + matricula + "' , id_curso1 = " + idCurso1F + " , " +
		" id_curso2 = " + idCurso2F + " , id_curso3 = " + idCurso3F + " WHERE STRCMP ( matricula , '" + matriculaAntiga + "' ) = 0 ;";
		return saida;
	}
	
	private String comandoAlunoMatricula( String matricula ) {
		return "SELECT * FROM aluno WHERE STRCMP ( matricula , '" + matricula + "' ) = 0 ;";
	}
	
	private String comandoRemoveAlunoMatricula( String matricula ) {
		return "DELETE from aluno WHERE STRCMP ( matricula , '" + matricula + "' ) = 0 ;";
	}

	private String comandoNomeAluno( String nome ) {
		return "SELECT id FROM aluno WHERE STRCMP ( nome , '" + nome + "' ) = 0 ;";
	}
	
	private String comandoMatriculaAluno( String matricula ) {
		return "SELECT id FROM aluno WHERE STRCMP ( matricula , '" + matricula + "' ) = 0 ;";
	}
	
	private String comandoCadastraAluno( String nome, String matricula ) {
		return "INSERT INTO aluno VALUES ( NULL, '" + nome + "', '" + matricula + "', NULL, NULL, NULL ) ;";
	}
	
	private String comandoPesquisaAluno( String nome ) {
		return "SELECT * FROM aluno WHERE nome LIKE '%" + nome + "%' ;";
	}
	
}
